module m3Vec

        use mPrecision

        implicit none

        interface new
                module procedure new_3vec
        end interface new

        interface operator(*)
                module procedure dot
        end interface

        interface write
                module procedure write_3vec
        end interface write

        type t3Vec
                private
                real(D) :: x(3)
        end type t3Vec

        private
        public :: t3Vec, new, write
        public :: length, operator(*)

contains

        pure subroutine new_3vec(vector, x, y, z)

                type(t3Vec), intent(out) :: vector
                real(D), intent(in) :: x, y, z

                vector%x = (/ x, y, z /)

        end subroutine new_3vec
                
        real(D) elemental function length(vector)

                type(t3Vec), intent(in) :: vector

                length = sqrt( sum(vector%x * vector%x) )

        end function length

        real(D) pure function dot(a, b)

                type(t3Vec), intent(in) :: a, b

                dot = dot_product(a%x, b%x)

        end function dot

        subroutine write_3vec(vector)

                type(t3Vec), intent(in) :: vector

                write(6, '(3e11.3)') vector%x

        end subroutine write_3vec

end module m3Vec
